package com.nokia.examplegame;

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class GameCanvasView extends GameCanvas {

	private GameThread gameThread;

	private GameLayerManager layerManager;

	private GameMIDlet midlet;

	private Image background;

	private Image player;

	private Image obstacle;

	private Image backgroundLayer;

	private Image instructionsImage;

	private Image pausedImage;

	private Image gameOverImage;

	private int gameTicks;

	private int gameScore;

	private boolean initialised;

	private boolean firstLoad;

	private boolean paused;

	private boolean gameOver;

	private int cornerX;

	private int cornerY;

	private int displayWidth;

	private int displayHeight;

	public GameCanvasView() {
		super(false);
		this.setFullScreenMode(true);
	}

	public void createCanvas(GameMIDlet midlet, Image instructionsImage,
			Image pausedImage, Image gameOverImage, Image background,
			Image player, Image obstacle, Image backgroundLayer) {
		this.gameTicks = 1500;
		this.gameScore = 0;
		this.initialised = false;
		this.paused = true;
		this.firstLoad = true;
		this.gameOver = false;
		this.instructionsImage = instructionsImage;
		this.pausedImage = pausedImage;
		this.gameOverImage = gameOverImage;
		this.midlet = midlet;
		this.background = background;
		this.player = player;
		this.obstacle = obstacle;
		this.backgroundLayer = backgroundLayer;
		this.gameThread = new GameThread();
	}

	private void checkKeys() {
		if (!gameOver) {
			int keyState = getKeyStates();
			if ((keyState & LEFT_PRESSED) != 0) {
				layerManager.setPlayerMovingLeft(true);
			}
			if ((keyState & RIGHT_PRESSED) != 0) {
				layerManager.setPlayerMovingLeft(false);
			}
			if ((keyState & UP_PRESSED) != 0) {
				layerManager.setPlayerJumping(true);
			}
		}
	}

	protected void updateGame() {

        gameTicks--;
		gameScore += layerManager.updateLayers(gameTicks);
		if (gameTicks == 0) {
			gameOver = true;
			gameThread.requestStop();
			midlet.gameOver();
		}

		Graphics g = getGraphics();
		paint(g);
		flushGraphics();

		synchronized (this) {
			try {
				wait(10);
			} catch (Exception e) {
			}
		}
	}

	public void paint(Graphics g) {
		if (!initialised) {
			cornerX = g.getClipX();
			cornerY = g.getClipY();
			displayWidth = g.getClipWidth();
			displayHeight = g.getClipHeight();
			layerManager = new GameLayerManager(cornerX, cornerY,
					displayHeight, displayWidth, player, obstacle,
					backgroundLayer);
			initialised = true;
		}
		g.drawImage(background, 0, 0, Graphics.LEFT | Graphics.TOP);
        
		drawScore(g);

		g.setColor(163, 84, 55);
		g.fillRect(cornerX, cornerY + displayHeight - this.backgroundLayer.getHeight(), displayWidth,
				displayHeight);
		try {
			layerManager.paint(g);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (firstLoad) {
			firstLoad = false;
			drawGreyOut(g);
			g.drawImage(instructionsImage, displayWidth / 2, displayHeight / 2,
					Graphics.HCENTER | Graphics.VCENTER);
		} else if (paused) {
			drawGreyOut(g);
			g.drawImage(pausedImage, displayWidth / 2, displayHeight / 2,
					Graphics.HCENTER | Graphics.VCENTER);
		} else if (gameOver) {
			drawGreyOut(g);
			g.drawImage(gameOverImage, displayWidth / 2, displayHeight / 2,
					Graphics.HCENTER | Graphics.VCENTER);
		}
	}

	private void drawGreyOut(Graphics g) {
		int[] buf = new int[displayWidth];
		for (int i = 0; i < displayWidth; i++) {
			buf[i] = 0x88ffffff;
		}
		g.drawRGB(buf, 0, 0, cornerX, cornerY, displayWidth, displayHeight,
				true);
	}

	private void drawScore(Graphics g) {
		Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
				Font.SIZE_SMALL);
		g.setFont(font);
		int width = font.stringWidth("Score: ");
		g.setColor(27, 179, 23);
		g.drawRect(5, 5, width + 30, 20);
		g.setColor(101, 101, 101);
		g.fillRect(6, 6, width + 29, 19);
		g.setColor(27, 179, 23);
		g.drawString("Score: " + gameScore, 7, 7, Graphics.TOP | Graphics.LEFT);
	}

	public void stopGame() {
		this.gameThread.requestStop();
	}

	public void playGame() {
		this.paused = false;
		this.gameThread.requestPlay();
	}

	public void pauseGame() {
		this.paused = true;
		updateGame();
		this.gameThread.requestPause();
	}

	class GameThread extends Thread {
		private boolean pause = true;

		private boolean stop = false;

		private boolean started = false;

		public void requestPlay() {
			this.pause = false;
			if (!started) {
				this.start();
				this.started = true;
			}
		}

		public void requestPause() {
			this.pause = true;
		}

		public void requestStop() {
			this.stop = true;
		}

		public void run() {
			while (!stop) {
				if (!pause) {
					checkKeys();
					updateGame();
				}
			}
		}
	}

	public void reset() {
        this.gameThread = null;
		this.createCanvas(midlet, instructionsImage, pausedImage,
				gameOverImage, background, player, obstacle, backgroundLayer);
		//updateGame();
		this.paused = false;
	}
}